diff options
Diffstat (limited to 'src/routes/projects/[id]/+page.svelte')
| -rw-r--r-- | src/routes/projects/[id]/+page.svelte | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/routes/projects/[id]/+page.svelte b/src/routes/projects/[id]/+page.svelte index c69d066..3d1aafe 100644 --- a/src/routes/projects/[id]/+page.svelte +++ b/src/routes/projects/[id]/+page.svelte @@ -1,5 +1,6 @@ <script lang="ts"> import { enhance } from '$app/forms'; + import { matchItems } from '$lib/components/fuzzy-search'; import { formatFrequency, parseIntervalToDays, @@ -18,6 +19,15 @@ const frequencyDays = $derived(parseIntervalToDays(frequency)); const editFrequencyDays = $derived(parseIntervalToDays(editFrequency)); + let showArchived = $state(false); + let archiveFilter = $state(''); + + const filteredArchived = $derived( + archiveFilter.trim() === '' + ? data.archived + : matchItems(data.archived, archiveFilter).map((m) => m.obj), + ); + const dateFormatter = new Intl.DateTimeFormat('fr-FR', { day: 'numeric', month: 'short', @@ -203,6 +213,48 @@ <p class="empty">Aucune routine</p> {/if} + {#if data.archived.length > 0} + <section class="archived-section"> + <button + class="archived-toggle" + type="button" + onclick={() => (showArchived = !showArchived)} + aria-expanded={showArchived} + > + <span class="chevron">{showArchived ? '▾' : '▸'}</span> + Archivées + <span class="count">{data.archived.length}</span> + </button> + {#if showArchived} + <input + class="form-input archived-search" + type="search" + bind:value={archiveFilter} + placeholder="Rechercher une routine archivée..." + autocomplete="off" + aria-label="Rechercher parmi les routines archivées" + /> + <ul class="item-list"> + {#each filteredArchived as routine (routine.id)} + <li class="item-row item-row--card archived-row"> + <a + class="routine-name" + href="/projects/{data.project.id}/routine/{routine.id}" + >{routine.name}</a + > + <span class="archived-date"> + archivée le {dateFormatter.format(new Date(routine.archivedAt))} + </span> + </li> + {/each} + </ul> + {#if filteredArchived.length === 0} + <p class="empty archived-empty">Aucune correspondance.</p> + {/if} + {/if} + </section> + {/if} + <footer class="page-footer"> <form method="POST" action="?/archiveProject" use:enhance> <button class="btn-archive" type="submit">Archiver le projet</button> @@ -308,6 +360,72 @@ color: var(--danger); } + .archived-section { + margin-top: 1.5rem; + display: flex; + flex-direction: column; + gap: 0.75rem; + } + + .archived-toggle { + align-self: flex-start; + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.375rem 0.75rem; + border: none; + border-radius: 0.625rem; + background: transparent; + color: var(--text-secondary); + font-family: inherit; + font-size: 0.875rem; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; + } + + .archived-toggle:hover { + background: var(--surface); + color: var(--text); + } + + .archived-toggle .chevron { + font-size: 0.75rem; + } + + .archived-toggle .count { + min-width: 1.25rem; + padding: 0 0.375rem; + border-radius: 9999px; + background: var(--surface); + text-align: center; + font-size: 0.75rem; + font-weight: 600; + } + + .archived-search { + width: 100%; + } + + .archived-row .routine-name { + flex-grow: 1; + color: var(--text-secondary); + } + + .archived-row .routine-name:hover { + color: var(--accent); + } + + .archived-date { + flex-shrink: 0; + font-size: 0.75rem; + color: var(--text-secondary); + } + + .archived-empty { + padding: 1rem 0; + } + .empty { margin-top: 1rem; padding: 2rem; |
